###########################################################################
#	$Id: labourTidy.p 49 2009-07-15 06:56:22Z donbeave $
###########################################################################

@CLASS
labourTidy

@USE
pf/tests/pfAssert.p
labour/tainting/labourTidyConfig.p

@OPTIONS
locals

#----- Static constructor -----

@auto[]
  ^if(def $MAIN:TIDY_PATH && -f $MAIN:TIDY_PATH){
    $self._TIDY_PATH[$MAIN:TIDY_PATH]
  }{
     $self._TIDY_PATH[/../bin/tidy]
   }

#----- Constructor -----

@create[hshConfig]
  $self._defaultOutputMethod[xhtml]

  ^_createLogs[]

#----- Public -----

@parseHTML[strData;hshConfig]
  $result[^parse[HTML;$strData;$hshConfig]]

@parseXHTML[strData;hshConfig]
  $result[^parse[XHTML;$strData;$hshConfig]]

@parseXML[strData;hshConfig]
  $result[^parse[XML;$strData;$hshConfig]]

@parse[strType;strData;hshConfig]
  ^pfAssert:isTrue(def $strData)[Data not specified.]

  $sOutput[^if(def $strType){$strType}{$_defaultOutputMethod}]

  $tOptions[^_makeOptions[$hshConfig]]

  ^tOptions.append{--output-${sOutput}}
  ^tOptions.append{yes}

  $fTidy[^file::exec[$_TIDY_PATH;$.stdin[$strData];$tOptions]]

  $result[$fTidy.text]

  ^if(def $fTidy.stderr){
    ^fTidy.stderr.save[/tidy_error.log]
    ^_createLogs[]
    ^_parsingLogs[$fTidy.stderr]
  }

@setOptions[hshConfig]
  ^config._config.add[$hshConfig]

@saveConfig[strFileName]
  $result[]

  ^config.save[$strFileName]

#----- Properties -----

@GET_config[]
  ^if(!def $self._config){
    $self._config[^labourTidyConfig::create[$self]]
  }
  $result[$self._config]

@GET_errors[]
  $result[$self._errors]

@GET_warnings[]
  $result[$self._warnings]

@GET_version[]
  $fVersion[^file::exec[$_TIDY_PATH;;-version]]

  $result[$fVersion.text]

#----- Private -----

@_makeOptions[hshConfig]
  $result[^table::create{arg}]

# очищаем опции отвечающие за формат вывода
# (формат вывода класс сам указывает во время вызова tidy)
  ^config._config.delete[outputHTML]
  ^config._config.delete[outputXHTML]
  ^config._config.delete[outputXML]

  ^config._config.foreach[sName;aData]{
    ^if($hshConfig is hash && ^hshConfig.contains[$sName]){
      $aData[$hshConfig.$sName]
    }

    ^result.append{--^config._restoreName[$sName]}
    ^result.append{^if($aData is bool){^if($aData){yes}{no}}{$aData}}
  }

@_createLogs[]
  $self._errors[^table::create{line	column	log}]
  $self._warnings[^table::create{line	column	log	type}]

@_parsingLogs[strLogs]
  $tMatches[^strLogs.match[^^line\s(\d+)\scolumn\s(\d+)\s-\s(Warning|Info|Error):\s(.+)^$][gmx]]

  ^if($tMatches){
    ^tMatches.menu{
      ^if($tMatches.3 eq "Error"){
        ^self._errors.append{$tMatches.1	$tMatches.2	$tMatches.4}
      }{
         ^self._warnings.append{$tMatches.1	$tMatches.2	$tMatches.4	$tMatches.3}
       }
    }
  }

@_execThrow[flData]
  ^throw[tidy.exec;status: $flData.status;$flData.stderr]